package com.ada.java8;

import java.io.*;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.security.AccessController;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class PersonApps {


    /**
     * 设置可访问对象的可访问权限为 true
     *
     * @param object 可访问的对象
     * @param <T>    类型
     * @return 返回设置后的对象
     */
    public static <T extends AccessibleObject> T setAccessible(T object) {
        return AccessController.doPrivileged(new SetAccessibleAction<>(object));
    }
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.setAge(1);
        p1.setName("a1");
        BiConsumer<Person, String> consumer = Person::setName;
        consumer.accept(p1,"1111");

        SFunction<Person,String> name=Person::getName;
        if (name instanceof Proxy) {

        }
        // 2. 反射读取
        try {
            Method method = name.getClass().getDeclaredMethod("writeReplace");
            System.out.println(method.getName());

            SerializedLambda invoke = (SerializedLambda) setAccessible(method).invoke(name);
            System.out.println(invoke.getImplMethodName());
            //return new ReflectLambdaMeta((SerializedLambda) ReflectionKit.setAccessible(method).invoke(func));
        } catch (Throwable e) {
            e.printStackTrace();


            try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
                 ObjectOutputStream oos = new ObjectOutputStream(baos)) {
                oos.writeObject(name);
                oos.flush();
                try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())) {
                    @Override
                    protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
                        Class<?> clazz = super.resolveClass(desc);
                        return clazz == java.lang.invoke.SerializedLambda.class ? SerializedLambda.class : clazz;
                    }

                }) {
                    SerializedLambda sss=     (SerializedLambda) ois.readObject();
                }
            } catch (Exception ee) {

                ee.printStackTrace();
                //throw new MybatisPlusException(e);
            }
            // 3. 反射失败使用序列化的方式读取
            //return new ShadowLambdaMeta(com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda.extract(func));
        }


        System.out.println(name.apply(p1));
        System.out.println(name.getClass().getName());


        Person p2 = new Person();
        p2.setAge(2);
        p2.setName("a2");

        Person p3 = new Person();
        p3.setAge(1);
        p3.setName("a3");

       List<Person> user=new ArrayList<>();
       user.add(p1);
        user.add(p2);
        user.add(p3);

        Stream<Person> ps = Stream.of(p1, p2, p3,p3);
        Map<Integer, List<Person>> fx = ps.collect(Collectors.groupingBy(Person::getAge));
        Iterator it = fx.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<Integer, List<Person>> persons = (Map.Entry) it.next();
            System.out.println("Age " + persons.getKey() + " = " + persons.getValue().size());
        }

        int age = user.stream().parallel().mapToInt(Person::getAge).reduce(0, Integer::sum);
        user.stream().filter(p->p.getAge()>0);
        System.out.println(age);
    }
}
